package rlyy.framework.grpc.server;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import rlyy.framework.core.common.enums.CommonEnum;
import rlyy.framework.core.common.enums.ExceptionEnum;
import rlyy.framework.core.common.response.ResultUtil;
import rlyy.framework.grpc.component.GrpcInterfaceGrpc;
import rlyy.framework.grpc.component.RequestMessage;
import rlyy.framework.grpc.component.ResponseMessage;
import rlyy.framework.grpc.strategy.single.ISingleRequestProcess;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;


/**
 * @author yuanqinglong
 * @since 2020/11/26 14:31
 */
@GrpcService
public class GrpcHandlerFacade extends GrpcInterfaceGrpc.GrpcInterfaceImplBase {

    static final Logger logger = LoggerFactory.getLogger(GrpcHandlerFacade.class);

    static final SerializeConfig SERIALIZE_CONFIG = new SerializeConfig();

    static {
        SERIALIZE_CONFIG.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;
    }

    /**
     * 所有定义的请求处理器
     */
    @Autowired
    private List<ISingleRequestProcess> iRequestProcesses;


    @Override
    public void handler(RequestMessage request, StreamObserver<ResponseMessage> responseObserver) {
        long startTime = System.currentTimeMillis();
        logger.info(" Request Method :{} ", request.getData());
        try {
            for (ISingleRequestProcess iRequestProcessor : iRequestProcesses) {
                if (iRequestProcessor.supportsHandler(request)) {
                    iRequestProcessor.requestHandler(request, responseObserver);
                    logger.info("Time-Consuming : {} ms", System.currentTimeMillis() - startTime);
                    return;
                }
            }
        } catch (Exception exception) {
            exception.printStackTrace();
            logger.error("has an error: ", exception);
            responseError(responseObserver, CommonEnum.SERVER_IS_BUSY);
            return;
        }
        responseError(responseObserver, CommonEnum.REQUEST_NOT_SUPPORTED);
    }

    /**
     * 返回错误信息
     * @param responseObserver response
     * @param exceptionEnum 错误提示
     */
    public static void responseError(StreamObserver<ResponseMessage> responseObserver, ExceptionEnum exceptionEnum) {
        String response = JSONObject.toJSONString(ResultUtil.error(exceptionEnum));
        responseObserver.onNext(ResponseMessage.newBuilder().setData(response).build());
        responseObserver.onCompleted();
    }


    /**
     * 返回信息
     * @param responseObserver response
     * @param result 返回信息提示
     */
    public static void responseSuccess(StreamObserver<ResponseMessage> responseObserver, Object result) {
        responseObserver.onNext(ResponseMessage.newBuilder().setData(JSONObject.toJSONString(result, SERIALIZE_CONFIG, SerializerFeature.WriteMapNullValue)).build());
        responseObserver.onCompleted();
    }

    public static void main(String[] args) {

    }
}
